package se.webbzon.boltzmann.editor.component.battlepropertylist;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import se.webbzon.boltzmann.battle.property.BattlePropertyFactory;
import se.webbzon.boltzmann.battle.property.BattlePropertyFactoryGroup;
import se.webbzon.boltzmann.editor.component.AbstractComponent;
import se.webbzon.boltzmann.editor.list.SortedListModel;

public class BPFList extends AbstractComponent {
	
	// Auto generated serial version UID
	private static final long serialVersionUID = -1087901697912831005L;
	
	// The input fields for this property frame
	private final JList<BattlePropertyFactory> factoryGroupList, factoryList;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public BPFList(BattlePropertyFactoryGroup factoryGroup, 
							List<BattlePropertyFactory> factories) {
		super("Battle Properties");
		Dimension 	cellDimension = new Dimension(256,64),
					listDimension = new Dimension(256,320);
		
		setLayout(new BoxLayout(this,BoxLayout.X_AXIS));

		// Create list models
		SortedListModel<BattlePropertyFactory> factoryGroupListModel = 
				new SortedListModel<BattlePropertyFactory>(
						BattlePropertyFactory.class,
						new BattlePropertyFactoryComparator(),
						factoryGroup.getFactories());

		DefaultListModel<BattlePropertyFactory> factoryListModel =
				new DefaultListModel<BattlePropertyFactory>();
		for (BattlePropertyFactory factory : factories)
			factoryListModel.addElement(factory);

		// Create from panel
		JPanel fromPanel = new JPanel();
		fromPanel.setLayout(new BoxLayout(fromPanel,BoxLayout.Y_AXIS));
		fromPanel.add(new JLabel("Available Factories:"));
		factoryGroupList = 
				new JList<BattlePropertyFactory>(factoryGroupListModel);
		factoryGroupList.setCellRenderer(new BPFListCell(cellDimension));
		JScrollPane factoryGroupScrollPane = 
				new JScrollPane(factoryGroupList);
		factoryGroupScrollPane.setPreferredSize(listDimension);
		fromPanel.add(factoryGroupScrollPane);
		add(fromPanel);

		// Create button panel
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
		buttonPanel.add(new JButton(new AddAction()));
		buttonPanel.add(new JButton(new RemoveAction()));
		add(buttonPanel);

		// Create to panel
		JPanel toPanel = new JPanel();
		toPanel.setLayout(new BoxLayout(toPanel,BoxLayout.Y_AXIS));
		toPanel.add(new JLabel("Added Factories:"));
		factoryList = 
				new JList<BattlePropertyFactory>(factoryListModel);
		factoryList.setCellRenderer(new BPFListCell(cellDimension));
		JScrollPane factoryScrollPane = 
				new JScrollPane(factoryList);
		factoryScrollPane.setPreferredSize(listDimension);
		toPanel.add(factoryScrollPane);
		add(toPanel);
	}

				
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns an enumeration of all the selected battle property factories. **/
	public Enumeration<BattlePropertyFactory> getBattlePropertyFactories() {
		return ((DefaultListModel<BattlePropertyFactory>) 
				factoryList.getModel()).elements();
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	/** An implementation of an abstract action used for the add button. **/
	private final class AddAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = 6647421649565288937L;

		/*============================================================
		Constructors
		============================================================*/
		
		public AddAction() {
			this.putValue(AbstractAction.NAME, "Add >>");
		}
		
		/*============================================================
		Public Methods
		============================================================*/

		@Override public void actionPerformed(ActionEvent arg0) {
			final BattlePropertyFactory factory = 
					factoryGroupList.getSelectedValue();
			if (factory != null)
				((DefaultListModel<BattlePropertyFactory>) 
					factoryList.getModel()).addElement(factory);
		}
		
	}
	
	/** An implementation of an abstract action used for the remove button. **/
	private final class RemoveAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = -5965604621157349225L;
		
		/*============================================================
		Constructors
		============================================================*/

		public RemoveAction() {
			this.putValue(AbstractAction.NAME, "Remove (X)");
		}
		
		/*============================================================
		Public Methods
		============================================================*/

		@Override public void actionPerformed(ActionEvent arg0) {
			int index = factoryList.getSelectedIndex();
			if (index >= 0)
				((DefaultListModel<BattlePropertyFactory>) 
						factoryList.getModel()).remove(index);
		}
		
	}
	
	/** An alphabetic battle property factory comparator. **/
	private static final class BattlePropertyFactoryComparator implements Comparator<BattlePropertyFactory> {

		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public int compare(	BattlePropertyFactory left, 
										BattlePropertyFactory right) {
			return left.getName().compareTo(right.getName());
		}
		
	}
}
